﻿using System;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using CLIHelper.Model;
using RpcHelper;
using RpcModel;

namespace CLIHelper.Helper
{
        /// <summary>
        /// 
        /// 
        /// </summary>
        internal class Helper
        {
                /// <summary>
                /// 
                /// </summary>
                /// <param name="body"></param>
                /// <param name="str"></param>
                public static void WriteShow (ApiBody body, StringBuilder str)
                {
                        str.AppendFormat ("\t\t/// <summary>\r\n\t\t/// {0}\r\n\t\t /// </summary>\r\n", body.Show);
                        if (body.Params.Length > 0)
                        {
                                body.Params.ForEach (c =>
                                {
                                        str.AppendFormat ("\t\t /// <param name=\"{0}\">{1}</param>\r\n", c.Name, c.Show);
                                });
                        }
                        if (body.Return.Type != PublicDataDic.VoidType)
                        {
                                str.AppendFormat ("\t\t/// <returns>{0}</returns>\r\n", body.Return.Show);
                        }
                }
                public static void WriteApiShow (ApiBody body, int mode, StringBuilder str)
                {
                        str.AppendFormat ("\t\t/// <summary>\r\n\t\t/// {0}\r\n\t\t /// </summary>\r\n", body.Show);
                        if (mode == 0)
                        {
                                str.AppendLine ("\t\t /// <param name=\"param\">参数</param>");
                        }
                        else if (mode == 1)
                        {
                                body.Params.ForEach (c =>
                                {
                                        if (c.ParamType == "basic")
                                        {
                                                str.AppendFormat ("\t\t /// <param name=\"{0}\">{1}</param>\r\n", c.Name, c.Show);
                                        }
                                });
                        }
                        if (body.IsPaging)
                        {
                                str.AppendLine ("\t\t /// <param name=\"count\">数据总数</param>");
                        }
                        if (body.Return.Type != PublicDataDic.VoidType)
                        {
                                str.AppendFormat ("\t\t/// <returns>{0}</returns>\r\n", body.Return.Show);
                        }
                }
                public static void WriteUiShow (ApiBody body, StringBuilder str)
                {
                        str.AppendFormat ("\t/// <summary>\r\n\t/// {0} UI参数实体\r\n\t/// </summary>\r\n", body.Show);
                }
                public static void WriteShow (ApiParam param, StringBuilder str)
                {
                        str.AppendFormat ("\t\t/// <summary>\r\n\t\t/// {0}\r\n\t\t /// </summary>\r\n", param.Show);
                }
                /// <summary>
                /// 
                /// </summary>
                /// <param name="nSpace"></param>
                /// <param name="name"></param>
                /// <param name="defName"></param>
                /// <returns></returns>
                public static string FormatNamespace (string nSpace, string name, string defName)
                {
                        if (name == nSpace)
                        {
                                return defName;
                        }
                        if (nSpace.StartsWith (name))
                        {
                                return nSpace.Remove (0, name.Length + 1);
                        }
                        else if (nSpace.IndexOf ('.') == -1)
                        {
                                return nSpace;
                        }
                        string[] t = nSpace.Split ('.');
                        return t[t.Length - 1];
                }
                public static string GetRootName (string name)
                {
                        string str = name.ToLower ();
                        if (str.EndsWith ("model"))
                        {
                                name = name.Remove (str.Length - 5);
                        }
                        if (str.StartsWith ("rpc"))
                        {
                                name = name.Remove (0, 3);
                        }
                        char[] chars = name.ToArray ();
                        chars[0] = char.ToUpper (chars[0]);
                        return new string (chars);
                }
                public static string GetNamespace (string name)
                {
                        string str = name.ToLower ();
                        if (str.EndsWith ("model"))
                        {
                                name = name.Remove (str.Length - 5);
                        }
                        if (str.StartsWith ("rpc"))
                        {
                                name = name.Remove (0, 3);
                        }
                        name = string.Concat (name, ".Gatewary.Modular");
                        char[] chars = name.ToArray ();
                        chars[0] = char.ToUpper (chars[0]);
                        return new string (chars);
                }
                public static string GetApiName (Type type)
                {
                        IRemoteConfig config = type.GetCustomAttribute<IRemoteConfig> ();
                        return config.SysDictate ?? type.Name;
                }
                public static bool CheckProperty (PropertyInfo pro)
                {
                        if (pro.GetCustomAttribute (ConstDic._AppIdAttr) != null)
                        {
                                return false;
                        }
                        return pro.CanWrite && pro.CanRead;
                }

                internal static ReturnTypeBody GetReturnType (Type type, out bool isPaging)
                {
                        Type parent = type.BaseType;
                        if (parent == ConstDic._RpcRemoteType || parent == ConstDic._RpcBroadcastType)
                        {
                                isPaging = false;
                                return new ReturnTypeBody (ConstDic._VoidType);
                        }
                        else if (parent == ConstDic._UpFileType)
                        {
                                isPaging = false;
                                return new ReturnTypeBody (ConstDic._UpFileType);
                        }
                        string name = parent.Name;
                        if (name.StartsWith ("RpcRemoteArray`1"))
                        {
                                isPaging = false;
                                return new ReturnTypeBody (parent.GenericTypeArguments[0], true);
                        }
                        if (name.StartsWith ("BasicPage`1"))
                        {
                                isPaging = true;
                                return new ReturnTypeBody (parent.GenericTypeArguments[0], true);
                        }
                        else
                        {
                                isPaging = false;
                                return new ReturnTypeBody (parent.GenericTypeArguments[0], false);
                        }
                }
                public static string FormatTypeName (Type type)
                {
                        switch (type.Name)
                        {
                                case "Int32":
                                        return "int";
                                case "Int16":
                                        return "short";
                                case "Int64":
                                        return "long";
                                case "String":
                                        return "string";
                                case "Object":
                                        return "object";
                                case "Boolean":
                                        return "bool";
                        }
                        return type.Name;
                }

                public static void CopDir (DirectoryInfo source, DirectoryInfo destFolder)
                {
                        foreach (FileInfo file in source.GetFiles ())
                        {
                                string path = Path.Combine (destFolder.FullName, file.Name);
                                if (System.IO.File.Exists (path))
                                {
                                        return;
                                }
                                file.CopyTo (path);
                        }
                        foreach (DirectoryInfo dir in source.GetDirectories ())
                        {
                                string path = Path.Combine (destFolder.FullName, dir.Name);
                                DirectoryInfo dest = new DirectoryInfo (path);
                                if (!dest.Exists)
                                {
                                        dest.Create ();
                                }
                                CopDir (dir, dest);
                        }
                }
        }
}
